/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2006，所有权利保留。
 * 
 * 文件名：	BUserProjectivePermAgent.java
 * 模块说明：	
 * 修改历史：
 * 2006-10-4 - lxm - 创建。
 */
package com.hd123.rumba.user.biz;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.type.Type;

import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.runtime.IBaseEntity;
import com.hd123.rumba.runtime.IManager;
import com.hd123.rumba.runtime.NamingMgr;
import com.hd123.rumba.runtime.OperateContext;
import com.hd123.rumba.user.IPermission;
import com.hd123.rumba.user.IRole;
import com.hd123.rumba.user.IRoleMgr;
import com.hd123.rumba.user.IRolePermission;
import com.hd123.rumba.user.IUser;
import com.hd123.rumba.user.IUserMgr;
import com.hd123.rumba.user.IUserPermission;

/**
 * 用户权限映射代理 | 业务层 | 实现类
 * <p>
 * 
 * 用户描述用户拥有的权限，包括用户直接拥有和通过角色拥有的权限的合集。<br>
 * 注：只提供查看权限的功能，不提供修改权限的功能。
 * 
 * @author lxm
 * 
 */
public class BUserProjectivePermAgent extends BPermAgent implements IBPermAgent {

  public void executeCommandsT(List<BPermissionCommand> cmds, OperateContext operate, long oca)
      throws BusinessException, HibernateException {
    if (true)
      throw new BusinessException("Never call me!");
  }

  @Override
  protected IBaseEntity getUserOrRole(String urUuid) throws BusinessException, HibernateException {
    return getUserMgr().getUser(urUuid);
  }

  @Override
  protected IManager getUserOrRoleMgr() throws BusinessException {
    return getUserMgr();
  }

  @Override
  protected Integer getHavingPermCount() throws BusinessException, HibernateException {
    Map permMap = new HashMap();

    List ups = getSession().find(
        "select up.permission.code from " + getUserMgr().lookupClass(IUserPermission.class) + " up"
            + " where up.user.uuid = ?", urUuid, Hibernate.STRING);
    for (int i = 0; i < ups.size(); i++) {
      String permCode = (String) ups.get(i);
      permMap.put(permCode, permCode);
    }

    IUser user = getUserMgr().getUser(urUuid);
    List roles = getUserMgr().createRolesList(user);
    for (int i = 0; i < roles.size(); i++) {
      IRole role = (IRole) roles.get(i);
      List rps = getSession().find(
          "select rp.permission.code from " + getRoleMgr().lookupClass(IRolePermission.class)
              + " rp" + " where rp.role.uuid = ?", role.getUuid(), Hibernate.STRING);
      for (int j = 0; j < rps.size(); j++) {
        String permCode = (String) rps.get(i);
        permMap.put(permCode, permCode);
      }
    }

    return Integer.valueOf(permMap.size());
  }

  @Override
  protected Integer getHavingPermCountInCFV(String cfvUuid) throws BusinessException,
      HibernateException {
    Map permMap = new HashMap();

    List ups = getSession().find(
        "select p.code from " + getUserMgr().lookupClass(IUserPermission.class) + " up"
            + " inner join up.permission p" + " where up.user.uuid = ? and p.cartFuncViewUuid = ?",
        new Object[] {
            urUuid, cfvUuid }, new Type[] {
            Hibernate.STRING, Hibernate.STRING });
    for (int i = 0; i < ups.size(); i++) {
      String permCode = (String) ups.get(i);
      permMap.put(permCode, permCode);
    }

    IUser user = getUserMgr().getUser(urUuid);
    List roles = getUserMgr().createRolesList(user);
    for (int i = 0; i < roles.size(); i++) {
      IRole role = (IRole) roles.get(i);
      List rps = getSession().find(
          "select p.code from " + getRoleMgr().lookupClass(IRolePermission.class) + " rp"
              + " inner join rp.permission p"
              + " where rp.role.uuid = ? and p.cartFuncViewUuid = ?", new Object[] {
              role.getUuid(), cfvUuid }, new Type[] {
              Hibernate.STRING, Hibernate.STRING });
      for (int j = 0; j < rps.size(); j++) {
        String permCode = (String) rps.get(j);
        permMap.put(permCode, permCode);
      }
    }

    return Integer.valueOf(permMap.size());
  }

  @Override
  protected Integer getHavingPermCountInProvider(String cfvUuid, BPermissionProvider provider)
      throws BusinessException, HibernateException {
    Map permMap = new HashMap();

    List ups = getSession().find(
        "select p.code from " + getUserMgr().lookupClass(IUserPermission.class) + " up"
            + " inner join up.permission p"
            + " where up.user.uuid = ? and p.cartFuncViewUuid = ? and p.provider.className = ?",
        new Object[] {
            urUuid, cfvUuid, provider.getClassName() }, new Type[] {
            Hibernate.STRING, Hibernate.STRING, Hibernate.STRING });
    for (int i = 0; i < ups.size(); i++) {
      String permCode = (String) ups.get(i);
      permMap.put(permCode, permCode);
    }

    IUser user = getUserMgr().getUser(urUuid);
    List roles = getUserMgr().createRolesList(user);
    for (int i = 0; i < roles.size(); i++) {
      IRole role = (IRole) roles.get(i);
      List rps = getSession().find(
          "select p.code from " + getRoleMgr().lookupClass(IRolePermission.class) + " rp"
              + " inner join rp.permission p"
              + " where rp.role.uuid = ? and p.cartFuncViewUuid = ? and p.provider.className = ?",
          new Object[] {
              role.getUuid(), cfvUuid, provider.getClassName() }, new Type[] {
              Hibernate.STRING, Hibernate.STRING, Hibernate.STRING });
      for (int j = 0; j < rps.size(); j++) {
        String permCode = (String) rps.get(j);
        permMap.put(permCode, permCode);
      }
    }

    return Integer.valueOf(permMap.size());
  }

  @Override
  protected Boolean hasPermission(IPermission pperm) throws BusinessException, HibernateException {
    List ups = getSession().find(
        "from " + getUserMgr().lookupClass(IUserPermission.class) + " up"
            + " where up.user.uuid = ? and up.permission.uuid = ?", new Object[] {
            urUuid, pperm.getUuid() }, new Type[] {
            Hibernate.STRING, Hibernate.STRING });
    if (ups.size() > 0)
      return Boolean.TRUE;

    IUser user = getUserMgr().getUser(urUuid);
    List roles = getUserMgr().createRolesList(user);
    for (int i = 0; i < roles.size(); i++) {
      IRole role = (IRole) roles.get(i);
      List rps = getSession().find(
          " from " + getRoleMgr().lookupClass(IRolePermission.class) + " rp"
              + " where rp.role.uuid = ? and rp.permission.uuid = ?", new Object[] {
              role.getUuid(), pperm.getUuid() }, new Type[] {
              Hibernate.STRING, Hibernate.STRING });
      if (rps.size() > 0)
        return Boolean.TRUE;
    }
    return Boolean.FALSE;
  }

  private IUserMgr userMgr = null;
  private IRoleMgr roleMgr = null;

  private IUserMgr getUserMgr() throws BusinessException {
    if (userMgr == null)
      userMgr = (IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class);
    return userMgr;
  }

  private IRoleMgr getRoleMgr() throws BusinessException {
    if (roleMgr == null)
      roleMgr = (IRoleMgr) NamingMgr.getInstance().lookupMgr(IRoleMgr.class);
    return roleMgr;
  }

}
